package com.tsfyun.common.base.util;

import lombok.extern.slf4j.Slf4j;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.*;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.time.temporal.TemporalUnit;
import java.util.Date;
import java.util.Locale;
import java.util.Objects;

/**
 * LocalDateTime工具类
 */
@Slf4j
public class LocalDateTimeUtils {

    /**
     * 短日期格式 (yyyy-MM-dd)
     */
    public static final String SHORT_DATE_PATTERN = "yyyy-MM-dd";

    //获取当前时间的LocalDateTime对象
    //LocalDateTime.now();

    //根据年月日构建LocalDateTime
    //LocalDateTime.of();

    //比较日期先后
    //LocalDateTime.now().isBefore(),
    //LocalDateTime.now().isAfter(),

    //Date转换为LocalDateTime
    public static LocalDateTime convertDateToLDT(Date date) {
        if (Objects.isNull(date)) {
            return null;
        }
        return LocalDateTime.ofInstant(date.toInstant(), ZoneId.systemDefault());
    }

    //LocalDateTime转换为Date
    public static Date convertLDTToDate(LocalDateTime time) {
        if (Objects.isNull(time)) {
            return null;
        }
        return Date.from(time.atZone(ZoneId.systemDefault()).toInstant());
    }


    //获取指定日期的毫秒
    public static Long getMilliByTime(LocalDateTime time) {
        if (Objects.isNull(time)) {
            return null;
        }
        return time.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();
    }

    //获取指定日期的秒
    public static Long getSecondsByTime(LocalDateTime time) {
        if (Objects.isNull(time)) {
            return null;
        }
        return time.atZone(ZoneId.systemDefault()).toInstant().getEpochSecond();
    }

    //获取指定时间的指定格式
    public static String formatTime(LocalDateTime time, String pattern) {
        if (Objects.isNull(time)) {
            return null;
        }
        return time.format(DateTimeFormatter.ofPattern(pattern));
    }

    public static String formatShort(LocalDateTime time) {
        if (Objects.isNull(time)) {
            return null;
        }
        return formatTime(time, SHORT_DATE_PATTERN);
    }

    //获取当前时间的指定格式
    public static String formatNow(String pattern) {
        return formatTime(LocalDateTime.now(), pattern);
    }

    //日期加上一个数,根据field不同加不同值,field为ChronoUnit.*
    public static LocalDateTime plus(LocalDateTime time, long number, TemporalUnit field) {
        if (Objects.isNull(time)) {
            return null;
        }
        return time.plus(number, field);
    }

    //日期减去一个数,根据field不同减不同值,field参数为ChronoUnit.*
    public static LocalDateTime minu(LocalDateTime time, long number, TemporalUnit field) {
        if (Objects.isNull(time)) {
            return null;
        }
        return time.minus(number, field);
    }

    /**
     * 毫秒转时间
     *
     * @param timeMills
     * @return
     */
    public static LocalDateTime mill2LocalDateTime(long timeMills) {
        return LocalDateTime.ofInstant(Instant.ofEpochMilli(timeMills), ZoneId.systemDefault());
    }

    /**
     * 获取两个日期的差  field参数为ChronoUnit.*
     *
     * @param startTime
     * @param endTime
     * @param field     单位(年月日时分秒)
     * @return
     */
    public static long betweenTwoTime(LocalDateTime startTime, LocalDateTime endTime, ChronoUnit field) {
        Period period = Period.between(LocalDate.from(startTime), LocalDate.from(endTime));
        if (field == ChronoUnit.YEARS) return period.getYears();
        if (field == ChronoUnit.MONTHS) return period.getYears() * 12 + period.getMonths();
        return field.between(startTime, endTime);
    }

    //获取一天的开始时间，2017,7,22 00:00
    public static LocalDateTime getDayStart(LocalDateTime time) {
        return time.withHour(0)
                .withMinute(0)
                .withSecond(0)
                .withNano(0);
    }

    //获取一天的结束时间，2017,7,22 23:59:59.999999999
    public static LocalDateTime getDayEnd(LocalDateTime time) {
        return time.withHour(23)
                .withMinute(59)
                .withSecond(59)
                .withNano(999999999);
    }

    public static Date convertByStringWithLength(String val) throws ParseException {
        if(StringUtils.isNotEmpty(val)) {
            Date convertDate;
            String formatPattern;
            if(val.contains("CST")){
                return new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy", Locale.US).parse(val);
            }
            int dateLength = val.length();
            switch (dateLength) {
                case 19:
                    formatPattern = "yyyy-MM-dd HH:mm:ss";
                    break;
                case 16:
                    formatPattern = "yyyy-MM-dd HH:mm";
                    break;
                case 14:
                    formatPattern = "yyyyMMddHHmmss";
                    break;
                case 12:
                    formatPattern = "yyyyMMddHHmm";
                    break;
                case 10:
                    formatPattern = "yyyy-MM-dd";
                    break;
                case 8:
                    formatPattern = "yyyyMMdd";
                    break;
                case 7:
                    formatPattern = "yyyy-MM";
                    break;
                case 6:
                    formatPattern = "yyyyMM";
                    break;
                default:
                    log.info("未定义格式，默认格式");
                    formatPattern = "yyyy-MM-dd HH:mm:ss";
                    break;
            }
            //SimpleDateFormat局部变量，线程安全
            SimpleDateFormat format = new SimpleDateFormat(formatPattern);
            convertDate = format.parse(val);
            return convertDate;
        } else {
            return null;
        }
    }

    public static LocalDateTime convert2LocalDateTimeByStringWithLength(String val) {
        if(StringUtils.isNotEmpty(val)) {
            int dateLength = val.length();
            switch (dateLength) {
                case 19:
                    //无需转换
                    val = val;
                    //formatPattern = "yyyy-MM-dd HH:mm:ss";
                    break;
                case 16:
                    //秒补零
                    val = val + ":00";
                    //formatPattern = "yyyy-MM-dd HH:mm";
                    break;
                case 13:
                    //分和秒补零
                    val = val + ":00:00";
                    //formatPattern = "yyyy-MM-dd HH";
                    break;
                case 14:
                    String reg14 = "(\\d{4})(\\d{2})(\\d{2})(\\d{2})(\\d{2})(\\d{2})";
                    val = val.replaceAll(reg14, "$1-$2-$3 $4:$5:$6");
                    //formatPattern = "yyyyMMddHHmmss";
                    break;
                case 12:
                    //秒补零
                    String reg12 = "(\\d{4})(\\d{2})(\\d{2})(\\d{2})(\\d{2})";
                    val = val.replaceAll(reg12, "$1-$2-$3 $4:$5");
                    val = val + ":00";
                    //formatPattern = "yyyyMMddHHmm";
                    break;
                case 10:
                    //formatPattern = "yyyy-MM-dd";
                    //时分秒都补零
                    val = val + " 00:00:00";
                    break;
                case 8:
                    String reg8 = "(\\d{4})(\\d{2})(\\d{2})";
                    val = val.replaceAll(reg8, "$1-$2-$3");
                    val = val + " 00:00:00";
                    //formatPattern = "yyyyMMdd";
                    break;
                default:
                    log.info("未定义匹配，值:{}",val);
                    break;
            }
            DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
            LocalDateTime convertLocalDateTime =  LocalDateTime.parse(val,dateTimeFormatter);
            return convertLocalDateTime;
        } else {
            return null;
        }
    }

    public static LocalDateTime parse(String val,String formatter){
        return LocalDateTime.parse(val,DateTimeFormatter.ofPattern(formatter));
    }

    public static LocalDateTime convertLocalDate(){
        return convertLocalDate(LocalDate.now());
    }
    public static LocalDateTime convertLocalDate(LocalDate localDate){
        return LocalDateTime.parse(localDate.format(DateTimeFormatter.ofPattern("yyyy-MM-dd")) + " 00:00:00",DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
    }

    public static LocalDateTime convertLocalAddHourMinute(LocalDateTime localDateTime,String time){
        return LocalDateTime.parse(convertLocalAddHourMinuteStr(localDateTime,time),DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
    }
    public static String convertLocalAddHourMinuteStr(LocalDateTime localDateTime,String time){
        return localDateTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd")) + " "+time+":00";
    }

    public static LocalDateTime convertLocalDateRemoveSecond(){
        return LocalDateTime.parse(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm")) + ":00",DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
    }
}
